package speech.hmm;

import be.ac.ulg.montefiore.run.jahmm.Hmm;
import be.ac.ulg.montefiore.run.jahmm.Observation;
import be.ac.ulg.montefiore.run.jahmm.Opdf;
import be.ac.ulg.montefiore.run.jahmm.OpdfFactory;

public class LeftRightHmm<O extends Observation> extends Hmm<O> {
	private int delta;
	
	public LeftRightHmm(int nbStates, int delta) {
		super(nbStates);
		this.delta = delta;
		setDefaultParameters();
	}
	
	public LeftRightHmm(int nbStates, OpdfFactory<? extends Opdf<O>> opdfFactory, int delta) {
		super(nbStates, opdfFactory);
		this.delta = delta;
		setDefaultParameters();
	}
	
	public int getDelta() {
		return delta;
	}
	
	public void setDelta(int newDelta) {
		this.delta = newDelta;
	}
	
	private void setDefaultParameters() {
		setDefaultPis();
		setDefaultTransitions();
	}
	
	/**
	 * By default, the left-to-right HMM will start in state 0.
	 */
	private void setDefaultPis() {
		this.setPi(0, 1);
		
		for (int i = 1; i < this.nbStates(); ++ i) {
			this.setPi(i, 0);
		}
	}
	
	/**
	 * Set default transition probabilities.
	 * If j < i, Aij = 0.
	 * If j > i + delta, Aij = 0.
	 */
	private void setDefaultTransitions() {
		for (int i = 0; i < this.nbStates(); ++ i) {
			int counter = 0;
			for (int j = 0; j < this.nbStates(); ++ j) {
				if (j < i) {
					this.setAij(i, j, 0);
					counter ++;
				}
				if (j > i + this.delta) {
					this.setAij(i, j, 0);
					counter ++;
				}
			}
			double prob = (double) 1 / (this.nbStates() - counter);
			for (int j = 0; j < this.nbStates(); ++ j) {
				if (this.getAij(i, j) != 0) {
					this.setAij(i, j, prob);
				}
			}
		}
	}
}
